package com.cskaoyan.service.impl;

import com.cskaoyan.bean.data.PageData;
import com.cskaoyan.mapper.MarketCartMapper;
import com.cskaoyan.mapper.MarketCouponMapper;
import com.cskaoyan.mapper.MarketCouponUserMapper;
import com.cskaoyan.model.*;
import com.cskaoyan.service.CouponService;
import com.cskaoyan.service.CouponUserService;
import com.cskaoyan.util.CouponUserStaticSatuts;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

@Service
public class CouponUserServiceImpl implements CouponUserService {

    @Autowired
    CouponService couponService;

    @Autowired
    MarketCouponUserMapper couponUserMapper;
    @Autowired
    MarketCouponMapper couponMapper;

    @Autowired
    MarketCartMapper cartMapper;

    @Override
    public List checkout(int userId, Integer couponId, BigDecimal goodsTotalPrice) {
        // 创建一个resultList，用于封装 优惠劵id、可用的优惠劵数量、优惠金额(最大)
        List resultList = new ArrayList<>();
        // 创建example用于查询用户可用的优惠劵
        MarketCouponUserExample example = new MarketCouponUserExample();
        // 定义可用优惠劵数量，默认是0
        Integer availableCouponLength = 0;
        // 定义优惠劵id，默认是前端传来的couponId
        Integer cId = couponId;
        // 定义最大优惠金额(最终存储)，默认是0
        BigDecimal disCount = new BigDecimal(0);
        // 如果couponId<=0，则查询可用的优惠劵数量
        if (couponId <= 0) {
            // 定义最大优惠金额(临时变量)，初值为0
            BigDecimal maxDiscount = new BigDecimal(0);
            // 构造查询条件，userId为隐含条件，状态为0表示未使用
            example.createCriteria().andDeletedEqualTo(false)
                    .andUserIdEqualTo(userId)
                    .andCouponIdEqualTo(couponId)
                    .andStatusEqualTo((short) 0);
            // 条件查询得到可用的优惠劵列表
            List<MarketCouponUser> marketCouponUsers = couponUserMapper.selectByExample(example);
            // 遍历比较出最大的优惠金额并得到该优惠劵id
            for (MarketCouponUser couponUser : marketCouponUsers) {
                // 通过主键从Market_Coupon表中查询到优惠劵
                MarketCoupon marketCoupon = couponMapper.selectByPrimaryKey(couponUser.getCouponId());
                // 得到优惠劵的满减金额(=优惠金额)
                BigDecimal discount = marketCoupon.getDiscount();
                // 判断选中的商品总额是否满足使用优惠劵的最小消费金额
                if (marketCoupon.getMin().compareTo(goodsTotalPrice) <= 0) {
                    // 如果满足，则用户可用的优惠劵数量+1
                    availableCouponLength++;
                }
                // 判断当前满减金额是否大于所存的最大满减金额
                if (discount.compareTo(maxDiscount) >= 0) {
                    // 如果大于，就覆盖掉小的那个
                    maxDiscount = discount;
                    // 同时保存该优惠劵id
                    cId = marketCoupon.getId();
                }
            }
            // couponId>0 就根据前端提供的优惠劵id查询到该优惠劵
        } else {
            // 通过couponId(主键)查询到优惠劵
            MarketCoupon marketCoupon = couponMapper.selectByPrimaryKey(couponId);
            // 并得到该优惠劵的满减金额(=优惠金额)
            disCount = marketCoupon.getDiscount();
        }
        // 将最终的优惠劵id、可用优惠劵数量、优惠金额 通通存到resultList当中
        resultList.add(0, cId);
        resultList.add(1, availableCouponLength);
        resultList.add(2, disCount);
        // 返回结果的list
        return resultList;
    }

    @Override
    public PageData findCouponListById(Integer status, Integer page, Integer limit, Integer userId) {
        PageData pageData = new PageData();

        MarketCouponUserExample userExample = new MarketCouponUserExample();
        int status1 = status;
        userExample.createCriteria()
                .andDeletedEqualTo(false)
                .andUserIdEqualTo(userId)
                .andStatusEqualTo((short) status1);
        userExample.setOrderByClause("add_time desc");
        //分页处理
        PageHelper.startPage(page, limit);
        List<MarketCouponUser> marketCouponUsers = couponUserMapper.selectByExample(userExample);

        List<MarketCoupon> marketCoupons = new ArrayList<>();
        for (MarketCouponUser marketCouponUser : marketCouponUsers) {
            MarketCoupon marketCoupon = couponMapper.selectByPrimaryKey(marketCouponUser.getCouponId());
            // 对得到的coupon进行时间的修改，因为有的优惠券时间是null，因为他是领取之后算时间的，要用户的优惠券表对他的起止时间进行设置
            marketCoupon.setStartTime(marketCouponUser.getStartTime());
            marketCoupon.setEndTime(marketCouponUser.getEndTime());
            // list添加优惠券信息封装到pageData中
            marketCoupons.add(marketCoupon);
        }
        //封装数据
        PageInfo pageInfo = new PageInfo(marketCouponUsers);

        pageData.setLimit(limit);
        pageData.setPages(pageInfo.getPages());
        pageData.setTotal((int) pageInfo.getTotal());
        pageData.setPage(page);
        pageData.setList(marketCoupons);

        return pageData;
    }

    /**
     * 将提交的 优惠券添加到用户账户当中
     *
     * @param couponId
     * @param userId
     * @return
     */
    @Override
    public Integer receviceNewCoupon(Integer couponId, Integer userId) {
        MarketCoupon marketCoupon = couponMapper.selectByPrimaryKey(couponId);

        MarketCouponUserExample couponUserExample = new MarketCouponUserExample();
        // 这里先查询用户是否拥有这个优惠券，从而进行接下来用户拥有数量是否大于每个人能领取优惠券的最大数量
        couponUserExample.createCriteria().andDeletedEqualTo(false).andUserIdEqualTo(userId).andCouponIdEqualTo(couponId);
        List<MarketCouponUser> marketCouponUsers = couponUserMapper.selectByExample(couponUserExample);
        // 对用户领取该优惠券最大数量进行判断，如果大于limit则不允许领取，小于才可以领取
        if (marketCouponUsers.size() < marketCoupon.getLimit().intValue() || marketCoupon.getLimit().intValue() == 0) {
            MarketCouponUser couponUser = new MarketCouponUser();
            // 对优惠券的时间类型进行判断，从而对起止日期进行不同处理
            if (marketCoupon.getTimeType().intValue() == 0) {
                couponUser.setStatus((short) 0);
                couponUser.setCouponId(couponId);
                couponUser.setUserId(userId);
                couponUser.setAddTime(new Date());
                couponUser.setStartTime(new Date());
                couponUser.setEndTime(new Date(System.currentTimeMillis() + marketCoupon.getDays() * 24 * 3600000)); // 这里的 优惠券时间类型是从领取之后延长天数
                couponUser.setUpdateTime(new Date());
                couponUserMapper.insertSelective(couponUser);
            } else {
                // 这里的优惠券时间类型是起止时间
                couponUser.setStatus((short) 0);
                couponUser.setCouponId(couponId);
                couponUser.setUserId(userId);
                couponUser.setAddTime(new Date());
                couponUser.setStartTime(marketCoupon.getStartTime());
                couponUser.setEndTime(marketCoupon.getEndTime());
                couponUser.setUpdateTime(new Date());
                couponUserMapper.insertSelective(couponUser);
            }
            // 对领取后优惠券的数量进行修改，如果数量归零就删除，优惠券数量为0，就说明无线领取，所以total大于0的优惠券，数量减少到0的时候就执行逻辑删除
            if (marketCoupon.getTotal() > 1) {
                marketCoupon.setTotal(marketCoupon.getTotal() - 1);
                couponMapper.updateByPrimaryKeySelective(marketCoupon);
            } else if (marketCoupon.getTotal() == 1) {
                marketCoupon.setTotal(0);
                marketCoupon.setDeleted(true);
                couponMapper.updateByPrimaryKeySelective(marketCoupon);
            }
            // 添加了这里返回0
            return CouponUserStaticSatuts.USER_ADD_THE_COUPON;
        } else {
            // 未添加就返回1
            return CouponUserStaticSatuts.USER_OWNED_THE_COUPON;
        }

    }

    /**
     * 查询该用户所有的优惠券
     *
     * @param cartId
     * @param grouponRulesId
     * @param userId
     * @return
     */
    @Override
    public PageData getSelectList(Integer cartId, Integer grouponRulesId, Integer userId) {
        PageData pageData = new PageData();

        MarketCartExample cartExample = new MarketCartExample();

        cartExample.createCriteria().andDeletedEqualTo(false).andUserIdEqualTo(userId).andCheckedEqualTo(true);
        List<MarketCart> marketCarts = cartMapper.selectByExample(cartExample);
        // 计算订单金额
        BigDecimal moneyTotal = new BigDecimal(0);
        for (MarketCart marketCart : marketCarts) {
            moneyTotal = moneyTotal.add(marketCart.getPrice().multiply(new BigDecimal(marketCart.getNumber())));
        }
        // 查询所有未使用的优惠券，并未过期
        MarketCouponUserExample couponUserExample = new MarketCouponUserExample();
        couponUserExample.createCriteria()
                .andDeletedEqualTo(false)
                .andUserIdEqualTo(userId)
                .andEndTimeGreaterThan(new Date())
                .andStatusEqualTo((short) 0);
        couponUserExample.setOrderByClause("add_time desc");
        List<MarketCouponUser> marketCouponUsers = couponUserMapper.selectByExample(couponUserExample);

        // 封装返回数据
        List<Map<String, Object>> marketCoupons = new ArrayList<>();
        for (MarketCouponUser marketCouponUser : marketCouponUsers) {
            MarketCoupon marketCoupon = couponMapper.selectByPrimaryKey(marketCouponUser.getCouponId());
            // 对优惠券最低使用金额与订单金额进行比较，小于订单金额则加入selectlist
            if (marketCoupon.getMin().compareTo(moneyTotal) <= 0) {
                Map<String, Object> mapCoupon = new HashMap<>();
                mapCoupon.put("available", true);
                mapCoupon.put("cid", marketCoupon.getId());
                mapCoupon.put("desc", marketCoupon.getDesc());
                mapCoupon.put("endTime", marketCouponUser.getEndTime());
                mapCoupon.put("id", marketCouponUser.getId());
                mapCoupon.put("min", marketCoupon.getMin());
                mapCoupon.put("name", marketCoupon.getName());
                mapCoupon.put("startTime", marketCouponUser.getStartTime());
                mapCoupon.put("tag", marketCoupon.getTag());
                mapCoupon.put("discount", marketCoupon.getDiscount());
                marketCoupons.add(mapCoupon);
            }
        }
        pageData.setList(marketCoupons);
        pageData.setPage(1);
        pageData.setPages(1);
        pageData.setTotal(marketCoupons.size());
        pageData.setLimit(marketCoupons.size());

        return pageData;
    }


    /**
     * 领取兑换的优惠券
     *
     * @param code
     * @param userId
     * @return
     */
    @Override
    public Integer addExchangeCoupon(String code, Integer userId) {
        MarketCouponExample couponExample = new MarketCouponExample();
        couponExample.createCriteria()
                .andDeletedEqualTo(false)
                .andCodeEqualTo(code)
                .andTimeTypeEqualTo((short) 1)
                .andStartTimeLessThan(new Date())
                .andEndTimeGreaterThan(new Date())
                .andTypeEqualTo((short) 2);
        couponExample.or().andDeletedEqualTo(false).andCodeEqualTo(code).andTimeTypeEqualTo((short) 0).andTypeEqualTo((short) 2);
        List<MarketCoupon> marketCoupons = couponMapper.selectByExample(couponExample);
        // 判断输入的优惠券代码是否正确
        if ((marketCoupons == null || marketCoupons.isEmpty())) {
            return 3;
        }
        // 标记用户领取了几张优惠券
        int number = 0;
        for (MarketCoupon marketCoupon : marketCoupons) {
            // 通过不同时间类型，对用户的优惠券进行不同时间处理
            if (marketCoupon.getTimeType() == 1) {
                MarketCouponUserExample couponUserExample = new MarketCouponUserExample();
                couponUserExample.createCriteria().andDeletedEqualTo(false).andUserIdEqualTo(userId).andCouponIdEqualTo(marketCoupon.getId());
                List<MarketCouponUser> marketCouponUsers = couponUserMapper.selectByExample(couponUserExample);
                // 判断优惠券该用户是否领取
                if (marketCouponUsers == null || marketCouponUsers.isEmpty()) {
                    MarketCouponUser couponUser = new MarketCouponUser();
                    couponUser.setStatus((short) 0);
                    couponUser.setCouponId(marketCoupon.getId());
                    couponUser.setUserId(userId);
                    couponUser.setAddTime(new Date());
                    couponUser.setStartTime(marketCoupon.getStartTime());
                    couponUser.setEndTime(marketCoupon.getEndTime());
                    couponUser.setUpdateTime(new Date());
                    number = number + couponUserMapper.insertSelective(couponUser);//添加成功返回1 ,兑换的优惠券数量添加1
                }
                // 对领取后优惠券的数量进行修改，如果数量归零就删除，优惠券数量为0，就说明无线领取，所以total大于0的优惠券，数量减少到0的时候就执行逻辑删除
                if (marketCoupon.getTotal() > 1) {
                    marketCoupon.setTotal(marketCoupon.getTotal() - 1);
                    couponMapper.updateByPrimaryKeySelective(marketCoupon);
                } else if (marketCoupon.getTotal() == 1) {
                    marketCoupon.setTotal(0);
                    marketCoupon.setDeleted(true);
                    couponMapper.updateByPrimaryKeySelective(marketCoupon);
                }

            } else {
                // 这里的时间类型是领取后延长时间
                MarketCouponUserExample couponUserExample = new MarketCouponUserExample();
                couponUserExample.createCriteria().andDeletedEqualTo(false).andUserIdEqualTo(userId).andCouponIdEqualTo(marketCoupon.getId());
                List<MarketCouponUser> marketCouponUsers = couponUserMapper.selectByExample(couponUserExample);
                // 判断是否领取优惠券，没有领取就添加到用户的数据库当中
                if (marketCouponUsers == null || marketCouponUsers.isEmpty()) {
                    MarketCouponUser couponUser = new MarketCouponUser();
                    couponUser.setStatus((short) 0);
                    couponUser.setCouponId(marketCoupon.getId());
                    couponUser.setUserId(userId);
                    couponUser.setAddTime(new Date());
                    couponUser.setStartTime(new Date());
                    couponUser.setEndTime(new Date(System.currentTimeMillis() + 24 * marketCoupon.getDays() * 36000000)); // 从当前时间延长优惠券的期限市场
                    couponUser.setUpdateTime(new Date());
                    number = number + couponUserMapper.insertSelective(couponUser); //添加成功返回1 ,兑换的优惠券数量添加1
                }
                // 对领取后优惠券的数量进行修改，如果数量归零就删除，优惠券数量为0，就说明无线领取，所以total大于0的优惠券，数量减少到0的时候就执行逻辑删除
                if (marketCoupon.getTotal() > 1) {
                    marketCoupon.setTotal(marketCoupon.getTotal() - 1);
                    couponMapper.updateByPrimaryKeySelective(marketCoupon);
                } else if (marketCoupon.getTotal() == 1) {
                    marketCoupon.setTotal(0);
                    marketCoupon.setDeleted(true);
                    couponMapper.updateByPrimaryKeySelective(marketCoupon);
                }

            }
        }

        if (number == 0) {
            return 0;       // 什么也没领到，全有
        } else if (number == marketCoupons.size()) {
            return 1;      // 全部都有
        } else {
            return 2;       // 有一部分优惠券，其他没有
        }
    }

    /**
     * 本方法查找 用户所有可以使用的优惠券
     *
     * @param userId
     * @param couponId
     * @return
     */
    @Override
    public List<MarketCouponUser> findCouponById(Integer userId, List<MarketCart> marketCarts) {
        MarketCouponUserExample couponUserExample = new MarketCouponUserExample();
        // 返回状态是未使用的优惠券并且截止时间大于现在
        couponUserExample.createCriteria().andDeletedEqualTo(false).andUserIdEqualTo(userId).andEndTimeGreaterThan(new Date()).andStatusEqualTo((short) 0);

        List<MarketCouponUser> marketCouponUsers = couponUserMapper.selectByExample(couponUserExample);

        BigDecimal money = new BigDecimal(0);
        //计算订单金额
        for (MarketCart marketCart : marketCarts) {
            money = money.add(marketCart.getPrice().multiply(new BigDecimal(marketCart.getNumber())));
        }

        List<MarketCouponUser> collect = new ArrayList<>();
        for (MarketCouponUser marketCouponUser : marketCouponUsers) {
            MarketCoupon couponById = couponService.findCouponById(marketCouponUser.getCouponId());
            // 最小金额小于订单金额的，才可以加入到返回list当中，从而在controller中返回list的长度
            if (money.compareTo(couponById.getMin()) >= 0) {
                collect.add(marketCouponUser);
            }
        }


        return collect;
    }

    /**
     * 查找指定优惠券
     *
     * @param userId
     * @param userCouponId
     * @return
     */
    @Override
    public MarketCouponUser findByUserCouponId(Integer userId, Integer userCouponId) {
        MarketCouponUserExample couponUserExample = new MarketCouponUserExample();
        //查找用户所拥有的制定的优惠券
        couponUserExample.createCriteria()
                .andDeletedEqualTo(false)
                .andUserIdEqualTo(userId)
                .andIdEqualTo(userCouponId);
        List<MarketCouponUser> marketCouponUsers = couponUserMapper.selectByExample(couponUserExample);
        // 这里是对异常数据的处理，如果该用户一个优惠券都没有，那么就返回空
        MarketCouponUser couponUser = marketCouponUsers != null && !marketCouponUsers.isEmpty() ? marketCouponUsers.get(0) : new MarketCouponUser();

        return couponUser;
    }
}


